/**
 * 时间处理工具库
 * 提供常用的时间格式化和转换功能
 */

/**
 * 格式化日期对象为指定格式的字符串
 * @param {Date|number|string} date - 日期对象、时间戳或日期字符串
 * @param {string} format - 输出格式，例如 'yyyy-MM-dd HH:mm:ss'
 * @returns {string} 格式化后的日期字符串
 */
function formatDate(date, format = 'yyyy-MM-dd HH:mm:ss') {
    if (!date) return '';

    // 如果是时间戳字符串，转换为数字
    if (typeof date === 'string' && !isNaN(date)) {
        date = parseInt(date);
    }

    // 如果是时间戳，转换为日期对象
    if (typeof date === 'number') {
        date = new Date(date);
    }

    // 如果是日期字符串，转换为日期对象
    if (typeof date === 'string') {
        date = new Date(date);
    }

    // 检查是否为有效日期
    if (isNaN(date.getTime())) {
        return '';
    }

    const o = {
        'M+': date.getMonth() + 1, // 月份
        'd+': date.getDate(), // 日
        'H+': date.getHours(), // 小时
        'm+': date.getMinutes(), // 分
        's+': date.getSeconds(), // 秒
        'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
        'S': date.getMilliseconds() // 毫秒
    };

    // 替换年份
    if (/(y+)/.test(format)) {
        format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
    }

    // 替换其他时间字段
    for (const k in o) {
        if (new RegExp('(' + k + ')').test(format)) {
            format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
        }
    }

    return format;
}

/**
 * 获取当前时间的格式化字符串
 * @param {string} format - 输出格式，例如 'yyyy-MM-dd HH:mm:ss'
 * @returns {string} 格式化后的当前时间字符串
 */
function getCurrentTime(format = 'yyyy-MM-dd HH:mm:ss') {
    return formatDate(new Date(), format);
}

/**
 * 获取当前日期的格式化字符串（不含时间）
 * @param {string} format - 输出格式，例如 'yyyy-MM-dd'
 * @returns {string} 格式化后的当前日期字符串
 */
function getCurrentDate(format = 'yyyy-MM-dd') {
    return formatDate(new Date(), format);
}

/**
 * 获取当前时间戳（毫秒）
 * @returns {number} 当前时间戳
 */
function getTimestamp() {
    return new Date().getTime();
}

/**
 * 将时间戳转换为日期对象
 * @param {number} timestamp - 时间戳（毫秒）
 * @returns {Date} 日期对象
 */
function timestampToDate(timestamp) {
    return new Date(timestamp);
}

/**
 * 将日期字符串转换为日期对象
 * @param {string} dateStr - 日期字符串，例如 '2023-05-15'
 * @returns {Date} 日期对象
 */
function stringToDate(dateStr) {
    return new Date(dateStr);
}

/**
 * 获取两个日期之间的天数差
 * @param {Date|string|number} date1 - 第一个日期
 * @param {Date|string|number} date2 - 第二个日期
 * @returns {number} 天数差
 */
function getDaysBetween(date1, date2) {
    const d1 = new Date(date1).getTime();
    const d2 = new Date(date2).getTime();
    const diff = Math.abs(d1 - d2);
    return Math.floor(diff / (1000 * 60 * 60 * 24));
}

/**
 * 在指定日期上增加或减少天数
 * @param {Date|string|number} date - 基准日期
 * @param {number} days - 要增加或减少的天数（正数增加，负数减少）
 * @returns {Date} 新的日期对象
 */
function addDays(date, days) {
    const result = new Date(date);
    result.setDate(result.getDate() + days);
    return result;
}

/**
 * 在指定日期上增加或减少月数
 * @param {Date|string|number} date - 基准日期
 * @param {number} months - 要增加或减少的月数（正数增加，负数减少）
 * @returns {Date} 新的日期对象
 */
function addMonths(date, months) {
    const result = new Date(date);
    result.setMonth(result.getMonth() + months);
    return result;
}

/**
 * 判断一个日期是否在另一个日期之前
 * @param {Date|string|number} date1 - 第一个日期
 * @param {Date|string|number} date2 - 第二个日期
 * @returns {boolean} 如果 date1 在 date2 之前返回 true，否则返回 false
 */
function isBefore(date1, date2) {
    return new Date(date1) < new Date(date2);
}

/**
 * 判断一个日期是否在另一个日期之后
 * @param {Date|string|number} date1 - 第一个日期
 * @param {Date|string|number} date2 - 第二个日期
 * @returns {boolean} 如果 date1 在 date2 之后返回 true，否则返回 false
 */
function isAfter(date1, date2) {
    return new Date(date1) > new Date(date2);
}

/**
 * 判断一个日期是否在两个日期之间
 * @param {Date|string|number} date - 要判断的日期
 * @param {Date|string|number} startDate - 开始日期
 * @param {Date|string|number} endDate - 结束日期
 * @returns {boolean} 如果 date 在 startDate 和 endDate 之间返回 true，否则返回 false
 */
function isBetween(date, startDate, endDate) {
    const d = new Date(date);
    return d >= new Date(startDate) && d <= new Date(endDate);
}

/**
 * 获取指定日期是星期几
 * @param {Date|string|number} date - 日期
 * @param {boolean} [chinese=false] - 是否返回中文星期几
 * @returns {string|number} 如果 chinese 为 true，返回中文星期几；否则返回数字（0-6，0 表示星期日）
 */
function getDayOfWeek(date, chinese = false) {
    const d = new Date(date);
    const day = d.getDay();

    if (chinese) {
        const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
        return weekdays[day];
    }

    return day;
}

/**
 * 获取指定月份的天数
 * @param {number} year - 年份
 * @param {number} month - 月份（1-12）
 * @returns {number} 该月的天数
 */
function getDaysInMonth(year, month) {
    return new Date(year, month, 0).getDate();
}

/**
 * 获取当前季度
 * @param {Date|string|number} [date=new Date()] - 日期
 * @returns {number} 季度（1-4）
 */
function getQuarter(date = new Date()) {
    const d = new Date(date);
    const month = d.getMonth() + 1;
    return Math.ceil(month / 3);
}

// 导出所有函数
export {
    formatDate,
    getCurrentTime,
    getCurrentDate,
    getTimestamp,
    timestampToDate,
    stringToDate,
    getDaysBetween,
    addDays,
    addMonths,
    isBefore,
    isAfter,
    isBetween,
    getDayOfWeek,
    getDaysInMonth,
    getQuarter
};
